<template>
  <view class="tv-area">
    <slot></slot>
  </view>
</template>

<script>
/**
 * tv-area 焦点区域
 * @description 定义焦点区域
 * @property { defaultFocusArea } 默认焦点区域
 * @property { triggerClick } 焦点移动后是否触发点击事件
 */
import mixin from '../../mixin/mixin.js';

export default {
  name: 'TvArea',
  componentName: 'TvArea',
  mixins: [mixin],
  provide() {
    return {
      tvArea: this
    };
  },
  inject: ['tvPage'],
  props: {
    // 默认焦点区域
    defaultFocusArea: {
      type: Boolean,
      default: false
    },
    // 焦点移动后是否触发点击事件
    triggerClick: {
      type: Boolean,
      default: false
    }
  },
  computed: {
    // 是否获得焦点
    hasFocus() {
      return this.focusFlag;
    }
  },
  data: () => ({
    focusFlag: false, // 焦点标志
    focused: null, // 焦点对象
    rect: {}, // 节点信息
    children: [] // 子组件
  }),
  watch: {
    defaultFocusArea: {
      immediate: true,
      handler(val) {
        val && this.setFocusArea();
      }
    }
  },
  methods: {
    /**
    * 派遣按键事件
    * @param {String} keyType 按键类型
    * @param {Number} keyCode 按键编码
    */
    dispatchKeyEvent(keyType, keyCode) {
      // 已获得焦点
      if (this.hasFocus) {
        // 有焦点对象，向焦点对象派遣按键事件
        if (this.focused) {
          return this.focused.dispatchKeyEvent(keyType, keyCode);
        }
        // 没有焦点对象，寻找焦点view
        this.findFocusView();
      }
    },
    /**
    * 设置焦点区域对象
    */
    setFocusArea() {
      this.focusFlag = true;
      this.tvPage.focused = this;
      !this.focused && this.findFocusView();
    },
    /**
    * 寻找焦点
    */
    findFocusView() {
      if (this.children.length) {
        const view = this.children.find(v => v.$options.componentName === 'TvView');
        view && view.setFocusView();
      }
    }
  },
  async mounted() {
    const rect = await this.$getRect('.tv-area');
    this.rect = Object.assign({}, rect, { uid: this._uid });
    this.tvPage.children.push(this);
  }
};
</script>
